package com.hfjyz.tutor.tutorcall.service;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.transaction.annotation.Transactional;

import com.hfjyz.base.bean.SearchCondition;
import com.hfjyz.base.constant.BaseConstant;
import com.hfjyz.base.entity.CallEntity;
import com.hfjyz.base.entity.TutorEntity;
import com.hfjyz.base.exception.BaseException;
import com.hfjyz.base.util.ExcelUtil;
import com.hfjyz.tutor.tutor.bean.TutorBean;
import com.hfjyz.tutor.tutor.dao.TutorDao;
import com.hfjyz.tutor.tutorcall.bean.TutorCallBean;
import com.hfjyz.tutor.tutorcall.bean.TutorCallExcelBean;
import com.hfjyz.tutor.tutorcall.bean.TutorCallSearchBean;
import com.hfjyz.tutor.tutorcall.dao.TutorCallDao;
import com.hfjyz.tutor.tutorcall.entity.TutorCallEntity;

public class TutorCallService {
    private static final Log SYS_LOG = LogFactory.getLog(BaseConstant.SYS_LOG);

    private TutorCallDao dao = null;
    
    private TutorDao tutorDao = null;

    public TutorCallDao getDao() {
        return dao;
    }

    public void setDao(TutorCallDao dao) {
        this.dao = dao;
    }

    public TutorDao getTutorDao() {
        return tutorDao;
    }

    public void setTutorDao(TutorDao tutorDao) {
        this.tutorDao = tutorDao;
    }

    public List<TutorCallBean> findTutorCall(SearchCondition cond,
            TutorCallSearchBean tutorCallSearch) throws BaseException {
        try {
            List<TutorCallEntity> entityList = null;
            if (tutorCallSearch != null) {
                entityList = dao.findCall(cond, tutorCallSearch.getWhereClause("call", "tutor"),
                        tutorCallSearch.getParamList());
            } else {
                entityList = dao.findCall(cond, null, null);
            }

            List<TutorCallBean> beanList = new ArrayList<TutorCallBean>();
            for (TutorCallEntity entity : entityList) {
                TutorCallBean bean = new TutorCallBean(entity);
                beanList.add(bean);
            }

            SYS_LOG.info("老师调用信息取得成功。");
            return beanList;
        } catch (Exception e) {
            SYS_LOG.error("老师调用信息取得失败！", e);
            throw new BaseException("老师调用信息取得失败！", e);
        }
    }

    public long getTutorCallCount(TutorCallSearchBean tutorCallSearch) throws BaseException {
        try {
            long count = 0L;
            if (tutorCallSearch != null) {
                count = dao.countCall(" TutorEntity tutor ", "tutor",
                        tutorCallSearch.getWhereClause("call", "tutor"),
                        tutorCallSearch.getParamList());
            } else {
                count = dao.countCall(" TutorEntity tutor ", "tutor", null, null);
            }
            SYS_LOG.info("老师调用信息总数取得成功。 总数=" + count);

            return count;
        } catch (Exception e) {
            SYS_LOG.error("老师调用信息总数取得失败！", e);
            throw new BaseException("老师调用信息总数取得失败！", e);
        }
    }

    @Transactional
    public void saveTutorCall(List<TutorCallBean> beanList) throws BaseException {
        for (TutorCallBean bean : beanList) {
            saveTutorCall(bean);
        }
    }

    @Transactional
    public void saveTutorCall(TutorCallBean bean) throws BaseException {
        try {
            String msg = bean.validate();
            if (msg != null && !msg.isEmpty()) {
                throw new BaseException(msg);
            }
            CallEntity entity = null;
            boolean isAdd = false;
            if (bean.getId() != null) {
                entity = dao.get(bean.getId());
            } else {
                long count = dao.countCallByTargetAndName(bean.getCallName(), 
                        bean.getTarget().getId());
                if (count > 0) {
                    throw new BaseException("指定的老师调用信息已经存在，请确认！");
                }
                entity = new CallEntity();
                isAdd = true;
            }
            mergeEntity(bean, entity);

            dao.saveOrUpdate(entity);
            if (isAdd) {
                // 更新调用次数
                TutorEntity tutor = tutorDao.get(bean.getTarget().getId());
                tutor.setCallTimes(tutor.getCallTimes() + 1);
                tutorDao.saveOrUpdate(tutor);
            }

            SYS_LOG.info("老师调用信息保存成功。 tutorCall=" + bean.toString());
        } catch (BaseException e) {
            SYS_LOG.error(e.getMessage(), e);
            throw e;
        } catch (Exception e) {
            SYS_LOG.error("老师调用信息保存失败！", e);
            throw new BaseException("老师调用信息保存失败！", e);
        }
    }

    private void mergeEntity(TutorCallBean bean, CallEntity e) {
        e.setCallName(bean.getCallName());
        e.setCallReason(bean.getCallReason());
        e.setCallRemark(bean.getCallRemark());
        e.setCallType(dao.getType());
        e.setId(bean.getId());
        e.setTargetId(bean.getTarget().getId());
        e.setCallAim(bean.getCallAim());
    }

    @Transactional
    public void deleteTutorCall(List<Integer> idList) throws BaseException {
        try {
            for (Integer id : idList) {
                CallEntity call = dao.get(id);
                TutorEntity tutor = tutorDao.get(call.getTargetId());
                tutor.setCallTimes(tutor.getCallTimes() - 1);

                dao.delete(id);
                tutorDao.saveOrUpdate(tutor);
            }
            SYS_LOG.info("老师调用删除成功。 idList=" + idList.toString());
        } catch (Exception e) {
            SYS_LOG.error("老师调用删除失败！", e);
            throw new BaseException("老师调用删除失败！", e);
        }
    }

    public TutorCallBean updateInitTutorCall(Integer id) throws BaseException {
        try {
            CallEntity call = dao.get(id);
            TutorEntity tutor = dao.findTargetById(call.getTargetId());
            TutorCallBean bean = new TutorCallBean(call, tutor);

            SYS_LOG.info("取得老师信息成功。 bean=" + bean);

            return bean;
        } catch (Exception e) {
            SYS_LOG.error("取得老师信息失败！", e);
            throw new BaseException("取得老师信息失败！", e);
        }
    }

    public Workbook exportTutorCall(String templatePath, List<TutorCallExcelBean> tutorCallList)
            throws BaseException {
        InputStream inputXLStream = null;
        try {
            inputXLStream = new BufferedInputStream(new FileInputStream(templatePath));
            ExcelUtil<TutorCallExcelBean> util = new ExcelUtil<TutorCallExcelBean>();
            
            return util.writeToExcel(inputXLStream, tutorCallList, BaseConstant.EXCEL_TUTOR_BEAN_LIST);
        } catch (Exception e) {
            throw new BaseException("导出Excel失败！");
        }
    }

    public List<TutorBean> findAllTutor() throws BaseException {
        try {
            List<TutorEntity> entityList = tutorDao.findAll();

            List<TutorBean> beanList = new ArrayList<TutorBean>();
            for (TutorEntity entity : entityList) {
                TutorBean bean = new TutorBean(entity);
                beanList.add(bean);
            }

            SYS_LOG.info("取得所有老师信息成功。");
            return beanList;
        } catch (Exception e) {
            SYS_LOG.error("取得所有老师信息失败。", e);
            throw new BaseException("取得所有老师信息失败。", e);
        }
    }
}
